package com.bms.api.base.aop;

import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.bms.api.base.annotation.AccessLimit;
import com.bms.api.util.JwtHelper;
import com.bms.common.base.common.exception.EnumSvrResult;
import com.bms.common.base.common.util.RenderUtil;
import com.feilong.core.Validator;

@Service
public class AccessInterceptor  extends HandlerInterceptorAdapter{
	
	@Resource
	private RedisTemplate<String, Integer> redisTemplate;
	
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		if(handler instanceof HandlerMethod) {
			String openId = getUserOpenId(request);
			HandlerMethod hm = (HandlerMethod)handler;
			AccessLimit accessLimit = hm.getMethodAnnotation(AccessLimit.class);
			if(accessLimit == null) {
				return true;
			}
			int seconds = accessLimit.seconds();
			int maxCount = accessLimit.maxCount();
			boolean needLogin = accessLimit.needLogin();
			String key = "access_"+request.getRequestURI();
			if(needLogin) {
				if(Validator.isNullOrEmpty(openId)){
					render(response,EnumSvrResult.ERROR_TOKEN);
					return false;
				}
				key += "_" + openId;
			}
			Integer count =redisTemplate.opsForValue().get(key);
	    	if(count == null) {
	    		redisTemplate.opsForValue().set(key,1,seconds,TimeUnit.SECONDS);
	    	}else if(count < maxCount) {
	    		redisTemplate.opsForValue().increment(key,1);
	    	}else {
	    		render(response,EnumSvrResult.ACCESS_LIMIT_REACHED);
	    		return false;
	    	}
		}
		return true;
	}
	
	private void render(HttpServletResponse response, EnumSvrResult result)throws Exception {
		RenderUtil.renderJson(response, result);
	}

	private String getUserOpenId(HttpServletRequest request) {
		String token = request.getHeader("token");
		if(Validator.isNotNullOrEmpty(token)){
			return JwtHelper.getOpenId(token);
		}
		return null;
	}
	
}
